package com.sys.plat.db;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.sys.plat.bean.GftSort;
import com.sys.plat.util.HQLUtil;
@SuppressWarnings("unchecked")
public class HibernateDao extends HibernateDaoSupport {
	protected final Log log = LogFactory.getLog(getClass());

	/**
	 * insert
	 * 
	 * @param o
	 * @return
	 */
	public void saveObject(Object o) {
		getHibernateTemplate().save(o);
	}

	/**
	 * select
	 * 
	 * @param clazz
	 * @param id
	 * @return
	 */
	public Object getObject(Class<?> clazz, Serializable id) {
		return getHibernateTemplate().get(clazz, id);
	}

	/**
	 * select * from clazz
	 * 
	 * @param clazz
	 * @return
	 */
	
	public List getObjects(Class clazz) {
		return getHibernateTemplate().loadAll(clazz);
	}

	/**
	 * 根据HQL得出列表，无分页
	 * 
	 * @param HQL
	 *            FROM Right WHERE LIKE ?;
	 *            listByHql(FROM Right WHERE LIKE ?,?,"%name%","aaa","AAAA");
	 * @return
	 */
	public List listByHql(final String HQL, final String... params) {
		List<String> list = null;
		if (params != null && params.length > 0) {
			list = new ArrayList<String>();
			for (String param : params) {
				list.add(param);
			}
		}
		return listByHql(HQL, list);
	}

	public List listByHql(final String HQL, final List paramlist) {
		if (paramlist == null) {
			return getHibernateTemplate().find(HQL);
		} else
			return getHibernateTemplate().executeFind(new HibernateCallback() {
				public Object doInHibernate(Session s)
						throws HibernateException {
					Query query = s.createQuery(HQL);
					int paramlistsize = paramlist.size();
					for (int i = 0; i < paramlistsize; i++) {
						String param = (String) paramlist.get(i);
						query.setString(i, param);
					}
                    return query.list();
				}
			});
	}

	public void delObject(Class clazz, Serializable id) {
		getHibernateTemplate().delete(getObject(clazz, id));
	}

	public void delObject(Object obj) {
		getHibernateTemplate().delete(obj);
	}

	public List page(final String q, final int firstResult, final int maxResults) {

		return getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException {
				Query query = s.createQuery(q);
				query.setFirstResult(firstResult);
				query.setMaxResults(maxResults);
                return query.list();
			}
		});
	}

	/**
	 * 
	 * @param pageno
	 *            2
	 * @param pageSize
	 *            15
	 * @param HQL
	 *            "FROM Right WHERE name LIKE %a%;"
	 * @return
	 */
	public List page(int pageno, int pageSize, String HQL) {
		return page(HQL, (pageno - 1) * pageSize, pageSize);
	}

	/**
	 * @param seqname
	 * @return
	 */
	public Object getSequence(final String seqname) {
        return getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session s) throws HibernateException {
                StringBuffer sb = new StringBuffer();
                sb.append("SELECT ").append(seqname).append(
                        ".nextval AS id FROM dual");
                return s.createSQLQuery(sb.toString()).addScalar("id",
                        Hibernate.LONG).uniqueResult();
            }
        });
	}
	/**
	 * 
	 * @param HQL
	 *            "FROM Right WHERE name LIKE %a%;"
	 * @return
	 */
	public int getTotalCount(final String HQL) {
		String countHQL = HQL;
		if (HQL.toLowerCase().trim().indexOf("select") != 0) {
			countHQL = "SELECT COUNT(*) " + countHQL.replace("fetch","");
		}
		List list = getHibernateTemplate().find(countHQL);
		int count = 0;
		if (list.size() > 0) {
			count = ((Long) list.get(0)).intValue();
		}
		return count;
	}

	/**
	 * 
	 * @param HQL
	 *            "FROM Right WHERE name LIKE %a%;"
	 * @return
	 */
	public int getTotalCount(final String HQL, final List paramlist) {
		final String countHQL;
		if (HQL.toLowerCase().trim().indexOf("select") != 0) {
			countHQL = new StringBuilder().append("SELECT COUNT(*) ").append(HQL.replace("fetch","")).toString();
		} else
			countHQL = HQL.replace("fetch","");

		List list = getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException {
				Query query = s.createQuery(countHQL);
				int paramlistsize = paramlist.size();
				for (int i = 0; i < paramlistsize; i++)
					query.setString(i, (String) paramlist.get(i));
                return query.list();
			}
		});
		int count = 0;
		if (list.size() > 0) {
			count = ((Long) list.get(0)).intValue();
		}
		return count;
	}

	/**
	 * 
	 * @param o
	 *            update table
	 * @return
	 */
	public void updateObject(Object o) {
		getHibernateTemplate().update(o);
	}

    public void saveOrUpdateObject(Object o) {
        getHibernateTemplate().saveOrUpdate(o);
    }

	public int delete(String delHQL) {
		final String q = delHQL;
		Integer result = (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session s)
							throws HibernateException {
						Query query = s.createQuery(q);
						return new Integer(query.executeUpdate());
					}
				});
		return result.intValue();
	}
	
	public int delete(String delHQL,final List paramlist) {
		final String q = delHQL;
		Integer result = (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session s)
							throws HibernateException {
						Query query = s.createQuery(q);
						if(paramlist!=null){
							int paramlistsize = paramlist.size();
							for (int i = 0; i < paramlistsize; i++)
								query.setString(i, (String) paramlist.get(i));
						}
						return new Integer(query.executeUpdate());
					}
				});
		return result.intValue();
	}

	/**
	 * 
	 * @param updateHQL
	 *            UPDATE TreeNode SET xx= WHERE
	 * @return
	 */
	public int update(String updateHQL) {
		final String q = updateHQL;
		Integer result = (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session s)
							throws HibernateException {
						Query query = s.createQuery(q);
						return new Integer(query.executeUpdate());
					}
				});
		return result.intValue();
	}

	public int getTotalCount(String HQL, Map filterMap) {
		Map map = HQLUtil.filter(filterMap, HQL, "id");
		HQL = map.get("hql").toString();
		Object paramlist = map.get("params");
		if (paramlist != null && ((List) paramlist).size() > 0)
			return this.getTotalCount(HQL, (List) paramlist);
		return this.getTotalCount(HQL);
	}
	
	public List listWithPage(String HQL, Map filterMap, GftSort sort,
			int pageno, int pagesize) {
		List<String> sortList = null;
		if(sort.isOk()){
			sortList=new ArrayList<String> ();
			sortList.add(sort.getProperty());
			sortList.add(sort.getSortOrder());
		}
		return this.listWithPage(HQL, filterMap, sortList, pageno, pagesize);
	}
	public List listWithPage(String HQL, Map filterMap, List<String> sortList,
			int pageno, int pagesize) {
		Map map = HQLUtil.filter(filterMap, HQL, "id");
		HQL = map.get("hql").toString();
		HQL = HQLUtil.sortHQL(sortList, HQL, " order by id DESC");
		Object paramlist = map.get("params");
		if (paramlist != null && ((List) paramlist).size() > 0)
			return page(HQL, (pageno - 1) * pagesize, pagesize,
					(List) paramlist);
		return page(HQL, (pageno - 1) * pagesize, pagesize);
	}

	@SuppressWarnings("unchecked")
	public List listWithPage(String HQL, Map filterMap, GftSort sort,
			int pageno, int pagesize,List list) {
		Map map = HQLUtil.filter(filterMap, HQL, "id");
		HQL = map.get("hql").toString();
		List sortList = new ArrayList();
		if(sort.isOk()){
			sortList=new ArrayList<String> ();
			sortList.add(sort.getProperty());
			sortList.add(sort.getSortOrder());
		}
		HQL = HQLUtil.sortHQL(sortList, HQL, " order by id DESC");
		List paramlist = (List) map.get("params");
		list.addAll(paramlist);
		if (list != null && list.size() > 0)
			return page(HQL, (pageno - 1) * pagesize, pagesize, list);
		return page(HQL, (pageno - 1) * pagesize, pagesize);
	}

	
	public List page(final String hql, final int start, final int pagesize,
			final List paramlist) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			public Object doInHibernate(Session s) throws HibernateException {
				Query query = s.createQuery(hql);
				query.setFirstResult(start);
				query.setMaxResults(pagesize);
				int paramlistsize = paramlist.size();
				for (int i = 0; i < paramlistsize; i++) {
					String param = (String) paramlist.get(i);
					query.setString(i, param);
				}
                return query.list();
			}
		});
	}

	public int update(String updateHQL, String ... params) {
		List<String> paramlist = null;
		if(params!=null&&params.length>0){
			paramlist= new ArrayList<String>();
			for(String param: params){
				paramlist.add(param);
			}
		}
		return this.update(updateHQL, paramlist);
	}
	/**
	 * 
	 * @param updateHQL
	 *            UPDATE TreeNode SET xx= ?
	 * @return
	 */
	public int update(String updateHQL, final List paramlist) {
		final String q = updateHQL;
		Integer result = (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session s)
							throws HibernateException {
						Query query = s.createQuery(q);
						int paramlistsize = paramlist.size();
						for (int i = 0; i < paramlistsize; i++) {
							String param = (String) paramlist.get(i);
							query.setString(i, param);
						}
						return new Integer(query.executeUpdate());
					}
				});
		return result.intValue();
	}

	/**
	 * 查找指定字段最大值
	 * 
	 * @param HQL
	 * @param columnName
	 *            字段名称
	 * @return
	 */
	public int getMaxNum(final String HQL, String columnName) {
		String maxHQL = HQL;
		if (HQL.toLowerCase().trim().indexOf("select") != 0) {
            maxHQL = "SELECT MAX(" + columnName + ") " + maxHQL;
        }
		List list = getHibernateTemplate().find(maxHQL);
		int count = 0;
		if (null != list.get(0) && list.size() > 0)
			count = ((Long) list.get(0)).intValue();
		return count;
	}

	/**
	 * 
	 * @param sql
	 * @return
	 */
	public Object executeFunction(final String sql) {

        return getHibernateTemplate().execute(new HibernateCallback() {
            public Object doInHibernate(Session s) throws HibernateException {
                return s.createSQLQuery(sql);
                
            }
        });
	}
}
